package DataStructures;

import java.util.Scanner;

/**
 * @author ：ALi
 * @date ：Created in 2021/9/12 15:06
 * @description：用循环数组来实现队列
 * @modified By：
 * @version: 尚硅谷java数据结构与算法$
 */
public class CircleArrayDemo {
    public static void main(String[] args) {
        //初始化队列
        CircelArray queue = new CircelArray(4);
        //接收用户输入
        char key = ' ';
        //循环时用的
        boolean loop = true;
        //标准输入
        Scanner scanner = new Scanner(System.in);
        while (loop) {
            System.out.println("s(show):显示队列所有数据");
            System.out.println("e(exit):退出数列");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列取出数据");
            System.out.println("h(head):查看队列的头数据");
            key = scanner.next().charAt(0);//接收输入的第一个字符
            switch (key) {
                case 's':
                    queue.showQueueAllData();
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                case 'a':
                    try {
                        System.out.println("请输入要添加的数据：");
                        int data = scanner.nextInt();
                        queue.addQueue(data);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'g':
                    try {
                        int res = queue.getQueue();
                        System.out.printf("取出的数据为:%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());//抛的异常为getQueue中的RuntimeException
                    }
                    break;
                case 'h':
                    try {
                        int res = queue.showFront();
                        System.out.printf("头数据为：%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出!");

    }

}

/**
 * 循环数组实现队列类
 */
class CircelArray{
    private int maxSize;
    private int front;//从0开始，指向数组的第一个元素
    private int rear;//从0开始，指向数组最后一个元素的后一个元素
    private int[] array;

    /**
     * 构造方法
     */
    public CircelArray(int number){
        maxSize = number;
        front = 0;
        rear = 0;
        array = new int[maxSize];
    }
    /**
     * 判断队列是否满了
     * @return true：满了
     */
    public boolean isFull(){

//        return rear == MaxLength-1;//这个是没用循环的数组
        return (rear+1)%maxSize == front;
    }

    /**
     * 判断队列为空
     * @return true:空
     */
    public boolean isEmpty(){

//        return front == rear;//头尾相等为空//这个是没用循环的数组
        return front == rear;
    }

    /**
     * 添加数据到队列
     * @param number 新加的数据
     */
    public void addQueue(int number){
        if (isFull()){
            //抛异常处理
            throw new RuntimeException("队列已经满了，不能添加了！");
        }
        //与数组队不一样
        array[rear] = number;
        rear = (rear + 1)%maxSize;


    }

    /**
     * 取队列的数据(出队列)
     * @return 队列首部的元素
     */
    public int getQueue(){
        if(isEmpty()){
            //抛异常处理
            throw new RuntimeException("队列空，无法取数据");
        }
        //很容易出错
        int res = array[front];
        front = (front + 1) % maxSize;
        return res;

    }

    /**
     * 显示队列的所有数据
     */
    public void showQueueAllData(){
            if(isEmpty()){
                System.out.println("队列为空");
                return;
            }
            System.out.println("队列所有的数据如下：");

            for (int i = front;i < front+size();i++){
                System.out.printf("array[%d] = %d\n",i%maxSize,array[i%maxSize]);//格式化打印
            }
    }

    /**
     *  计算队列的个数
     */
    public int size(){
       return (rear+maxSize-front)%maxSize;
    }

    /**
     * 显示头数据
     */
    public int showFront(){
        if(isEmpty()){
            throw new RuntimeException("数列为空，没有头数据!");
        }
        return array[front];
    }

}